package require http


#This package fetches true random number from random.org
# if program gives you error and says "ok :", your random number quota may be used up. You may need to wait several hours for random.org becomes available again.
set rand_num 1
set rand_buffer_size 1000
# randomly pick one  option from give options.
proc randompick { options } {
    global rand_buffer rand_num rand_buffer_size
    if ![info exists rand_buffer] {
	set rand_buffer [getBuffer 0 $rand_num $rand_buffer_size]
    }
    set n [expr [llength $options]-1]
    if {$rand_num != $n} {
	set rand_num $n
	set rand_buffer [getBuffer 0 $rand_num $rand_buffer_size]
    }
    if {[llength $rand_buffer] == 1 } {
	set rand_buffer [getBuffer 0 $rand_num $rand_buffer_size]
    }
    set i [lindex $rand_buffer end]
    set rand_buffer [lreplace $rand_buffer end end]
    return [lindex $options $i]
}
#get num of interger betweein min and max from Random.org 
proc getBuffer { min max num } {
    set url "http://www.random.org/integers/?num=$num&min=$min&max=$max&col=1&base=10&format=html&rnd=new"
    if {[catch {::http::geturl $url} tok]} {
         error "HTTP Request failed: $tok"
     }
     if {[::http::ncode $tok] != 200} {
         set msg "[::http::status $tok] : [::http::error $tok]"
         ::http::cleanup $tok
         error $msg
     }
    set ret [::http::data $tok]
    ::http::cleanup $tok
    #puts $ret
    if [regexp  "<pre\\s+(.+?)>(.*?)</pre>" $ret match tag data ] {
	return [lrange [split $data] 0 end-1]
    }
}


# has ? probility to be true
proc prob { probility} {
   global prob_buffer prob_precision rand_buffer_size
    if ![info exists prob_buffer] {
	set prob_buffer [getDecimals $rand_buffer_size $prob_precision]
    }
    if {[llength $prob_buffer] < 3 } {
	set prob_buffer [getDecimals $rand_buffer_size $prob_precision]
    }
    set precison_for_prob [string length [lindex [split $probility .] end]]
    for {set i 0} { $i < [expr $prob_precision-$precison_for_prob]} {incr i} { append probility 0}
    set p [lindex $prob_buffer end]
    set prob_buffer [lreplace $prob_buffer end end]
    puts "$p $probility"
    if { $p <= $probility} { return 1 } else { return 0}
}

proc randomseed {} {
      global prob_buffer prob_precision rand_buffer_size
    if ![info exists prob_buffer] {
	set prob_buffer [getDecimals $rand_buffer_size $prob_precision]
    }
    if {[llength $prob_buffer] <5 } {
	set prob_buffer [getDecimals $rand_buffer_size $prob_precision]
    }
    set seed 1
    for {set i 0} {$i < 3} { incr i} {
      set p1 [expr ceil(100*[lindex $prob_buffer end])]
      set prob_buffer [lreplace $prob_buffer end end]
      set seed [expr $p1*$seed]
    }
    return [expr int($seed)]
}
# get decimal buffer 
proc getDecimals { {num 100} { precision 10}} {
    set url "http://www.random.org/decimal-fractions/?num=$num&dec=$precision&col=1&format=html&rnd=new"
    if {[catch {::http::geturl $url} tok]} {
         error "HTTP Request failed: $tok"
     }
     if {[::http::ncode $tok] != 200} {
         set msg "[::http::status $tok] : [::http::error $tok]"
         ::http::cleanup $tok
         puts "warning: cannot get random number, use pseudo random number"
         set pseudo {}
         for {set i 0} { $i <$num} {incr i} { lappend pseudo [expr rand() ]}
         return $pseudo
        # error $msg
     }
    set ret [::http::data $tok]
    ::http::cleanup $tok
    #puts $ret
    if [regexp  "<pre\\s+(.+?)>(.*?)</pre>" $ret match tag data ] {
	return [lrange [split $data] 0 end-1]
    }
}

set rand_num 1
set rand_buffer_size 30
set prob_precision 10

